package goshp

import (
//"fmt"
)

const (
	NULL_SHAPE    int32 = 0
	POINT         int32 = 1
	POLY_LINE     int32 = 3
	POLYGON       int32 = 5
	MULTI_POINT   int32 = 8
	POINT_Z      int32 = 11
	POLY_LINE_Z   int32 = 13
	POLYGON_Z     int32 = 15
	MULTI_POINT_Z int32 = 18
	POINT_M       int32 = 21
	POLY_LINE_M   int32 = 23
	POLYGON_M     int32 = 25
	MULTI_POINT_M int32 = 28
	MULTI_PATCH   int32 = 31
)


type FileHeader struct {
	FileCode   int32   //	Integer	Big	Byte 0 	9994
	Unused1    int32   //	0	Integer	Big	Byte 4
	Unused2    int32   //	0	Integer	Big	Byte 8
	Unused3    int32   //	0	Integer	Big	Byte 12
	Unused4    int32   //	0	Integer	Big	Byte 16
	Unused5    int32   //	0	Integer	Big	Byte 20
	FileLength int32   //	File Length	Integer	Big	Byte 24
	Version    int32   //	1000	Integer	Little	Byte 28
	ShapeType  int32   //	Shape Type	Integer	Little	Byte 32
	Xmin       float64 //	Double	Little	Byte 36
	Ymin       float64 //	Double	Little	Byte 44
	Xmax       float64 //	Double	Little	Byte 52
	Ymax       float64 //	Double	Little	Byte 60
	Zmin       float64 //	Double	Little	Byte 68*
	Zmax       float64 //	Double	Little	Byte 76*
	Mmin       float64 //	Double	Little	Byte 84*
	Mmax       float64 //	Double	Little	Byte 92*

	//* Unused, with value 0.0, if not Measured or Z type	
}

type RecordHeader struct {
	RecordNumber  int32
	ContentLength int32
}

type BBox struct {
	Xmin float64
	Ymin float64
	Xmax float64
	Ymax float64
}


type Point struct {
	X float64 // X coordinate
	Y float64 // Y coordinate
}


type PointM struct {
	X float64 // X coordinate
	Y float64 // Y coordinate
	Z float64 // Z coordinate
	M float64 // Measure	
}


type PointZ struct {
	X float64 // X coordinate
	Y float64 // Y coordinate
	M float64 // Measure	
}


type MultiPoint struct {
	Box       BBox    // Bounding Box
	NumPoints int32   // Number of Points
	Points    []Point // The Points in the Set
}


type MultiPointM struct {
	Box       BBox      // Bounding Box
	NumPoints int32     // Number of Points
	Points    []Point   // The Points in the Set
	Mmin      float64   // The minimum and manimum measure stored in MultiPointM	
	Mmax      float64   // The minimum and maximum measure stored in MultiPointM
	Marray    []float64 // Measures the length of slice equals NumPoints	
}


type MultiPointZ struct {
	Box       BBox      // Bounding Box
	NumPoints int32     // Number of Points
	Points    []Point   // The Points in the Set
	Zmin      float64   // The minimum and manimum measure stored in MultiPointZ	
	Zmax      float64   // The minimum and maximum measure stored in MultiPointZ
	Zarray    []float64 // Measures the length of slice equals NumPoints
	Mmin      float64   // The minimum and manimum measure stored in MultiPointM	
	Mmax      float64   // The minimum and maximum measure stored in MultiPointM
	Marray    []float64 // Measures the length of slice equals NumPoints		
}


type PolyLine struct {
	Box       BBox    // Bounding Box
	NumParts  int32   // Number of Parts
	NumPoints int32   // Total Number of Points
	Parts     []int32 // Index to First Point in Part
	Points    []Point // Points for All Parts
}


type PolyLineM struct {
	Box       BBox      // Bounding Box
	NumParts  int32     // Number of Parts
	NumPoints int32     // Total Number of Points
	Parts     []int32   // Index to First Point in Part
	Points    []Point   // Points for All Parts
	Mmin      float64   // The minimum and manimum measure stored in PolyLineM	
	Mmax      float64   // The minimum and maximum measure stored in PolyLineM
	Marray    []float64 // Measures the length of slice equals NumPoints	
}


type PolyLineZ struct {
	Box       BBox      // Bounding Box
	NumParts  int32     // Number of Parts
	NumPoints int32     // Total Number of Points
	Parts     []int32   // Index to First Point in Part
	Points    []Point   // Points for All Parts
	Zmin      float64   // The minimum and manimum measure stored in PolyLineZ	
	Zmax      float64   // The minimum and maximum measure stored in PolyLineZ
	Zarray    []float64 // Measures the length of slice equals NumPoints
	Mmin      float64   // The minimum and manimum measure stored in PolyLineZ	
	Mmax      float64   // The minimum and maximum measure stored in PolyLineZ
	Marray    []float64 // Measures the length of slice equals NumPoints	
}


type Polygon struct {
	RecordNumber int32   // Record Number
	Box          BBox    // Bounding Box
	NumParts     int32   // Number of Parts
	NumPoints    int32   // Total Number of Points 
	Parts        []int32 // Index to First Point in Part
	Points       []Point // Points for All Parts
}


type PolygonM struct {
	Box       BBox      // Bounding Box
	NumParts  int32     // Number of Parts
	NumPoints int32     // Total Number of Points
	Parts     []int32   // Index to First Point in Part
	Points    []Point   // Points for All Parts
	Mmin      float64   // The minimum and manimum measure stored in MultiPointM	
	Mmax      float64   // The minimum and maximum measure stored in MultiPointM
	Marray    []float64 // Measures the length of slice equals NumPoints	
}

/*
type PolygonZ struct {
	Box       BBox      // Bounding Box
	NumParts  int32     // Number of Parts
	NumPoints int32     // Total Number of Points
	Parts     []int32   // Index to First Point in Part
	Points    []Point   // Points for All Parts
	Zmin      float64   // The minimum and manimum measure stored in PolygonZ	
	Zmax      float64   // The minimum and maximum measure stored in PolygonZ
	Zarray    []float64 // Measures the length of slice equals NumPoints
	Mmin      float64   // The minimum and manimum measure stored in PolygonZ	
	Mmax      float64   // The minimum and maximum measure stored in PolygonZ
	Marray    []float64 // Measures the length of slice equals NumPoints	
}
*/

type PolygonZ struct {
	Polygon
	Zmin   float64   // The minimum and manimum measure stored in PolygonZ	
	Zmax   float64   // The minimum and maximum measure stored in PolygonZ
	Zarray []float64 // Measures the length of slice equals NumPoints
	Mmin   float64   // The minimum and manimum measure stored in PolygonZ	
	Mmax   float64   // The minimum and maximum measure stored in PolygonZ
	Marray []float64 // Measures the length of slice equals NumPoints	
}


type Feature interface {
	IsValid() bool
	RecordNumber() int32
	Serialize() []byte
	String() string
}



type Shape struct {
	ShapeType int32		// Type of shape 
	RecordNumber int32  // Record Number of the shape
	Box       BBox      // Bounding Box
	NumParts  int32     // Number of Parts
	NumPoints int32     // Total Number of Points
	Parts     []int32   // Index to First Point in Part
	Points    []Point   // Points for All Parts
	Zmin      float64   // The minimum and manimum measure stored in PolygonZ	
	Zmax      float64   // The minimum and maximum measure stored in PolygonZ
	Zarray    []float64 // Measures the length of slice equals NumPoints
	Mmin      float64   // The minimum and manimum measure stored in PolygonZ	
	Mmax      float64   // The minimum and maximum measure stored in PolygonZ
	Marray    []float64 // Measures the length of slice equals NumPoints	
}
